﻿using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;

namespace SW.Lite.Infrastructure.Helpers
{
    /// <summary>
    ///     序列化帮助类
    /// </summary>
    public class SerializeHelper
    {
        private static SerializeHelper _instance;

        /// <summary>
        /// Gets the instance.
        /// </summary>
        public static SerializeHelper Instance
        {
            get { return _instance ?? (_instance = new SerializeHelper()); }
        }

        /// <summary>
        ///     序列化对象至文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="target">对象</param>
        public void XmlSerializeToFile(string filePath, object target)
        {
            XmlSerializeToFile(filePath, target, Encoding.UTF8);
        }

        /// <summary>
        ///     序列化对象至文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="target">对象</param>
        /// <param name="encoding">编码</param>
        public void XmlSerializeToFile(string filePath, object target, Encoding encoding)
        {
            var targetType = target.GetType();
            var xmlSerializer = new XmlSerializer(targetType);
            using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                xmlSerializer.Serialize(fs, target);
            }
        }

        /// <summary>
        ///     序列化对象
        /// </summary>
        /// <param name="target">对象</param>
        public string XmlSerialize(object target)
        {
            return XmlSerialize(target, Encoding.UTF8);
        }

        /// <summary>
        ///     序列化对象
        /// </summary>
        /// <param name="target">对象</param>
        /// <param name="encoding">编码</param>
        public string XmlSerialize(object target, Encoding encoding)
        {
            var targetType = target.GetType();
            var xmlSerializer = new XmlSerializer(targetType);
            using (var ms = new MemoryStream())
            {
                xmlSerializer.Serialize(ms, target);
                using (var reader = new StreamReader(ms, encoding))
                {
                    return reader.ReadToEnd();
                }
            }
        }

        /// <summary>
        ///     反序列化文件
        /// </summary>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="filePath">文件路径</param>
        public TTarget XmlDeserializeFromFile<TTarget>(string filePath)
            where TTarget : class
        {
            return XmlDeserializeFromFile<TTarget>(filePath, Encoding.UTF8);
        }

        /// <summary>
        ///     反序列化文件
        /// </summary>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="filePath">文件路径</param>
        /// <param name="encoding">编码</param>
        public TTarget XmlDeserializeFromFile<TTarget>(string filePath, Encoding encoding)
            where TTarget : class
        {
            return XmlDeserializeFromFile(filePath, encoding, typeof(TTarget)) as TTarget;
        }

        /// <summary>
        ///     反序列化文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="targetType">目标类型</param>
        public object XmlDeserializeFromFile(string filePath, Type targetType)
        {
            return XmlDeserializeFromFile(filePath, Encoding.UTF8, targetType);
        }

        /// <summary>
        ///     反序列化文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="encoding">编码</param>
        /// <param name="targetType">目标类型</param>
        public object XmlDeserializeFromFile(string filePath, Encoding encoding, Type targetType)
        {
            if (!File.Exists(filePath))
                return null;

            using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                var xmlSerializer = new XmlSerializer(targetType);
                return xmlSerializer.Deserialize(fs);
            }
        }

        /// <summary>
        ///     反序列化XML字符串
        /// </summary>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="xmlStr">XML字符串</param>
        public TTarget XmlDeserialize<TTarget>(string xmlStr)
            where TTarget : class
        {
            return XmlDeserialize<TTarget>(xmlStr, Encoding.UTF8);
        }

        /// <summary>
        ///     反序列化XML字符串
        /// </summary>
        /// <typeparam name="TTarget">目标类型</typeparam>
        /// <param name="xmlStr">XML字符串</param>
        /// <param name="encoding">编码</param>
        public TTarget XmlDeserialize<TTarget>(string xmlStr, Encoding encoding)
            where TTarget : class
        {
            return XmlDeserialize(xmlStr, encoding, typeof(TTarget)) as TTarget;
        }

        /// <summary>
        ///     反序列化XML字符串
        /// </summary>
        /// <param name="xmlStr">XML字符串</param>
        /// <param name="targetType">目标类型</param>
        public object XmlDeserialize(string xmlStr, Type targetType)
        {
            return XmlDeserialize(xmlStr, Encoding.UTF8, targetType);
        }

        /// <summary>
        ///     反序列化XML字符串
        /// </summary>
        /// <param name="xmlStr">XML字符串</param>
        /// <param name="encoding">编码</param>
        /// <param name="targetType">目标类型</param>
        public object XmlDeserialize(string xmlStr, Encoding encoding, Type targetType)
        {
            var buffer = encoding.GetBytes(xmlStr);
            var xmlSerializer = new XmlSerializer(targetType);
            var ms = new MemoryStream(buffer);
            return xmlSerializer.Deserialize(ms);
        }
    }
}